﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Reflection;
using Newtonsoft.Json.Linq;

namespace DidaManager.Models.JsonConvert
{
    // 数据库JSON结构类
    /// <summary>
    /// 数据库中的网络配置类
    /// </summary>
    public class DatabaseNetworkConfig
    {
        [JsonPropertyName("lanMode")]
        public string LanMode { get; set; } = string.Empty;

        [JsonPropertyName("wanConfig")]
        public DatabaseWanConfig WanConfig { get; set; } = new DatabaseWanConfig();

        [JsonPropertyName("lanNetwork")]
        public DatabaseLanNetwork LanNetwork { get; set; } = new DatabaseLanNetwork();

        [JsonPropertyName("fourGNetwork")]
        public DatabaseFourGNetwork FourGNetwork { get; set; } = new DatabaseFourGNetwork();

        [JsonPropertyName("wifiNetwork")]
        public DatabaseWifiNetwork WifiNetwork { get; set; } = new DatabaseWifiNetwork();
    }

    /// <summary>
    /// 数据库中的WAN配置类
    /// </summary>
    public class DatabaseWanConfig
    {
        [JsonPropertyName("ipType")]
        public string IpType { get; set; } = string.Empty;

        [JsonPropertyName("ipAddress")]
        public string IpAddress { get; set; } = string.Empty;

        [JsonPropertyName("subnetMask")]
        public string SubnetMask { get; set; } = string.Empty;

        [JsonPropertyName("gateway")]
        public string Gateway { get; set; } = string.Empty;

        [JsonPropertyName("dns")]
        public string Dns { get; set; } = string.Empty;
    }

    /// <summary>
    /// 数据库中的LAN网络配置类
    /// </summary>
    public class DatabaseLanNetwork
    {
        [JsonPropertyName("gateway")]
        public string Gateway { get; set; } = string.Empty;

        [JsonPropertyName("subnetMask")]
        public string SubnetMask { get; set; } = string.Empty;

        [JsonPropertyName("startIp")]
        public string StartIp { get; set; } = string.Empty;

        [JsonPropertyName("endIp")]
        public string EndIp { get; set; } = string.Empty;
    }

    /// <summary>
    /// 数据库中的4G网络配置类
    /// </summary>
    public class DatabaseFourGNetwork
    {
        [JsonPropertyName("apn")]
        public string Apn { get; set; } = string.Empty;

        [JsonPropertyName("authType")]
        public string AuthType { get; set; } = string.Empty;

        [JsonPropertyName("username")]
        public string Username { get; set; } = string.Empty;

        [JsonPropertyName("password")]
        public string Password { get; set; } = string.Empty;
    }

    /// <summary>
    /// 数据库中的WiFi网络配置类
    /// </summary>
    public class DatabaseWifiNetwork
    {
        [JsonPropertyName("ssid")]
        public string Ssid { get; set; } = string.Empty;

        [JsonPropertyName("password")]
        public string Password { get; set; } = string.Empty;

        [JsonPropertyName("ipType")]
        public string IpType { get; set; } = string.Empty;

        [JsonPropertyName("ipAddress")]
        public string IpAddress { get; set; } = string.Empty;

        [JsonPropertyName("subnetMask")]
        public string SubnetMask { get; set; } = string.Empty;

        [JsonPropertyName("gateway")]
        public string Gateway { get; set; } = string.Empty;

        [JsonPropertyName("dns")]
        public string Dns { get; set; } = string.Empty;
    }

    // 最终配置文件结构类
    public class IPParam
    {
        [JsonPropertyName("IP")]
        public string IP { get; set; } = string.Empty;

        [JsonPropertyName("Mask")]
        public string Mask { get; set; } = string.Empty;

        [JsonPropertyName("GW")]
        public string GW { get; set; } = string.Empty;

        [JsonPropertyName("DNS")]
        public string DNS { get; set; } = string.Empty;
    }

    public class ETHConfig
    {
        [JsonPropertyName("IsDHCP")]
        public bool IsDHCP { get; set; } = false;

        [JsonPropertyName("IPParam")]
        public IPParam IPParam { get; set; } = new IPParam();
    }

    public class WNETConfig
    {
        [JsonPropertyName("APN")]
        public string APN { get; set; } = string.Empty;

        [JsonPropertyName("AuthType")]
        public string AuthType { get; set; } = string.Empty;

        [JsonPropertyName("User")]
        public string User { get; set; } = string.Empty;

        [JsonPropertyName("Passwd")]
        public string Passwd { get; set; } = string.Empty;
    }

    public class LAN
    {
        [JsonPropertyName("Gateway")]
        public string Gateway { get; set; } = string.Empty;

        [JsonPropertyName("NetMask")]
        public string NetMask { get; set; } = string.Empty;

        [JsonPropertyName("IPPool1")]
        public string IPPool1 { get; set; } = string.Empty;

        [JsonPropertyName("IPPool2")]
        public string IPPool2 { get; set; } = string.Empty;
    }

    public class WIFIConfig
    {
        [JsonPropertyName("IsDHCP")]
        public bool IsDHCP { get; set; } = false;

        [JsonPropertyName("IPParam")]
        public IPParam IPParam { get; set; } = new IPParam();

        [JsonPropertyName("SSID")]
        public string SSID { get; set; } = string.Empty;

        [JsonPropertyName("PWR")]
        public string PWR { get; set; } = string.Empty;
    }

    public class NetworkToDownloadFile
    {
        [JsonPropertyName("ETHConfig")]
        public ETHConfig ETHConfig { get; set; } = new ETHConfig();

        [JsonPropertyName("WNETConfig")]
        public WNETConfig WNETConfig { get; set; } = new WNETConfig();

        [JsonPropertyName("LAN")]
        public LAN LAN { get; set; } = new LAN();

        [JsonPropertyName("IsLans")]
        public bool IsLans { get; set; }

        [JsonPropertyName("WIFIConfig")]
        public WIFIConfig WIFIConfig { get; set; } = new WIFIConfig();

        /// <summary>
        /// 从数据库JSON字符串解析网络配置数据并转换为下载格式
        /// </summary>
        /// <param name="filePath">文件路径</param>
        public static void ParseDbJsonAndSave(string filePath)
        {
            if (!File.Exists(filePath))
            {
                throw new FileNotFoundException($"文件不存在: {filePath}");
            }

            string jsonContent = File.ReadAllText(filePath);
            if (string.IsNullOrEmpty(jsonContent))
            {
                throw new ArgumentException("JSON内容不能为空");
            }

            // 使用 JObject 解析 JSON
            JObject jsonObject = JObject.Parse(jsonContent);
            var databaseConfig = MapJsonToObject<DatabaseNetworkConfig>(jsonObject);

            var downloadConfig = ConvertToDownloadFormat(databaseConfig);
            SaveDownloadConfigToFile(downloadConfig, filePath);
        }

        /// <summary>
        /// 通用的 JSON 到对象映射方法
        /// </summary>
        /// <typeparam name="T">目标类型</typeparam>
        /// <param name="json">JSON对象</param>
        /// <returns>映射后的对象</returns>
        private static T MapJsonToObject<T>(JObject json) where T : class, new()
        {
            var obj = new T();
            var properties = typeof(T).GetProperties();

            foreach (var prop in properties)
            {
                var jsonPropertyName = GetJsonPropertyName(prop);
                if (json.TryGetValue(jsonPropertyName, out JToken? value) && value != null)
                {
                    SetPropertyValue(obj, prop, value);
                }
            }

            return obj;
        }

        /// <summary>
        /// 获取属性对应的 JSON 字段名
        /// </summary>
        /// <param name="prop">属性信息</param>
        /// <returns>JSON字段名</returns>
        private static string GetJsonPropertyName(PropertyInfo prop)
        {
            var jsonPropertyAttribute = prop.GetCustomAttribute<JsonPropertyNameAttribute>();
            return jsonPropertyAttribute?.Name ?? prop.Name;
        }

        /// <summary>
        /// 设置属性值，支持嵌套对象和集合
        /// </summary>
        /// <param name="obj">目标对象</param>
        /// <param name="prop">属性信息</param>
        /// <param name="value">JSON值</param>
        private static void SetPropertyValue(object obj, PropertyInfo prop, JToken value)
        {
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj), "目标对象不能为空");
            }

            try
            {
                if (prop.PropertyType == typeof(string))
                {
                    prop.SetValue(obj, value.ToString());
                }
                else if (prop.PropertyType == typeof(int))
                {
                    prop.SetValue(obj, value.ToObject<int>());
                }
                else if (prop.PropertyType == typeof(bool))
                {
                    prop.SetValue(obj, value.ToObject<bool>());
                }
                else if (prop.PropertyType.IsClass && prop.PropertyType != typeof(string))
                {
                    // 处理嵌套对象
                    if (value is JObject nestedJson)
                    {
                        var nestedObj = Activator.CreateInstance(prop.PropertyType);
                        if (nestedObj == null)
                        {
                            throw new InvalidOperationException($"无法创建类型 {prop.PropertyType.FullName} 的实例");
                        }

                        var nestedProperties = prop.PropertyType.GetProperties();

                        foreach (var nestedProp in nestedProperties)
                        {
                            var nestedJsonPropertyName = GetJsonPropertyName(nestedProp);
                            if (nestedJson.TryGetValue(nestedJsonPropertyName, out JToken? nestedValue) && nestedValue != null)
                            {
                                SetPropertyValue(nestedObj, nestedProp, nestedValue);
                            }
                        }

                        prop.SetValue(obj, nestedObj);
                    }
                }
            }
            catch (Exception ex)
            {
                // 记录日志或处理异常
                Console.WriteLine($"设置属性 {prop.Name} 值时发生错误: {ex.Message}");
            }
        }

        /// <summary>
        /// 将数据库配置转换为下载格式
        /// </summary>
        /// <param name="databaseConfig">数据库配置</param>
        /// <returns>下载配置</returns>
        private static NetworkToDownloadFile ConvertToDownloadFormat(DatabaseNetworkConfig databaseConfig)
        {
            var downloadConfig = new NetworkToDownloadFile
            {
                ETHConfig = new ETHConfig
                {
                    IsDHCP = databaseConfig.WanConfig.IpType.ToLower() == "dhcp",
                    IPParam = new IPParam
                    {
                        IP = databaseConfig.WanConfig.IpAddress,
                        Mask = databaseConfig.WanConfig.SubnetMask,
                        GW = databaseConfig.WanConfig.Gateway,
                        DNS = databaseConfig.WanConfig.Dns
                    }
                },
                WNETConfig = new WNETConfig
                {
                    APN = databaseConfig.FourGNetwork.Apn,
                    AuthType = databaseConfig.FourGNetwork.AuthType,
                    User = databaseConfig.FourGNetwork.Username,
                    Passwd = databaseConfig.FourGNetwork.Password
                },
                LAN = new LAN
                {
                    Gateway = databaseConfig.LanNetwork.Gateway,
                    NetMask = databaseConfig.LanNetwork.SubnetMask,
                    IPPool1 = databaseConfig.LanNetwork.StartIp,
                    IPPool2 = databaseConfig.LanNetwork.EndIp
                },
                IsLans = databaseConfig.LanMode.ToLower() == "dual",
                WIFIConfig = new WIFIConfig
                {
                    IsDHCP = databaseConfig.WifiNetwork.IpType.ToLower() == "dhcp",
                    IPParam = new IPParam
                    {
                        IP = databaseConfig.WifiNetwork.IpAddress,
                        Mask = databaseConfig.WifiNetwork.SubnetMask,
                        GW = databaseConfig.WifiNetwork.Gateway,
                        DNS = databaseConfig.WifiNetwork.Dns
                    },
                    SSID = databaseConfig.WifiNetwork.Ssid,
                    PWR = databaseConfig.WifiNetwork.Password
                }
            };

            return downloadConfig;
        }

        /// <summary>
        /// 将下载配置保存到文件
        /// </summary>
        /// <param name="downloadConfig">下载配置</param>
        /// <param name="filePath">文件路径</param>
        private static void SaveDownloadConfigToFile(NetworkToDownloadFile downloadConfig, string filePath)
        {
            string jsonContent = JsonSerializer.Serialize(downloadConfig, JsonSerializerOptionsManager.Compact);         
            File.WriteAllText(filePath, jsonContent);
        }
    }
}
